package tpf.jvm.course9;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 使用同步的线程安全的计数器
 * @author tpf
 *
 */
public class NonblockingCounterThread implements Runnable {
	
	private int threadId;
	private CountDownLatch threadsSignal;
	
	private static AtomicInteger number = new AtomicInteger(0);
	private static boolean flag = true;
	
	private static int MAX_NUMBER = 1000000;
	
	/**
	 * @param threadId
	 * @param threadsSignal
	 */
	public NonblockingCounterThread(int threadId, CountDownLatch threadsSignal) {
		super();
		this.threadId = threadId;
		this.threadsSignal = threadsSignal;
	}
	
	/**
	 * @return the threadId
	 */
	public int getThreadId() {
		return threadId;
	}

	public int increment() {
        int v = 0;
        do {
        	v = number.get();
        } while (!number.compareAndSet(v, v + 1));
        return v + 1;
	}

	@Override
	public void run() {
		while (flag) {
            if (increment() >= MAX_NUMBER) {
            	flag = false;
            }
		}
		threadsSignal.countDown();// 线程结束时计数器减1
		System.out.println(Thread.currentThread().getName() + "结束. 还有" + threadsSignal.getCount() + " 个线程");
	}
	
	public static void main(String args[]) {
        final int THREAD_NUMBER = 1000;
        try {
                long startMainTime = System.currentTimeMillis();
                CountDownLatch threadSignal = new CountDownLatch(THREAD_NUMBER);
                for (int i = 0; i < THREAD_NUMBER; i++) {
                        new Thread(new NonblockingCounterThread(i, threadSignal)).start();
                }
                // 等待所有子线程执行完
                threadSignal.await();
                System.out.println(Thread.currentThread().getName() + " done.");// 打印结束标记
                long duratingMainTime = System.currentTimeMillis() - startMainTime;

                System.out.println("All total time is: " + duratingMainTime + "ms");
                // System.out.println("Start Thread numbers: " + THREAD_NUMBER);
                // System.out.println("number is increased to: " + number);
        } catch (Exception e) {
                e.printStackTrace();
        }

	}
	
//	@Test
	/*public void testNonblockingCounterThread() {
		 final int THREAD_NUMBER = 1000;
         try {
                 long startMainTime = System.currentTimeMillis();
                 CountDownLatch threadSignal = new CountDownLatch(THREAD_NUMBER);
                 for (int i = 0; i < THREAD_NUMBER; i++) {
                         new Thread(new NonblockingCounterThread(i, threadSignal)).start();
                 }
                 // 等待所有子线程执行完
                 threadSignal.await();
                 System.out.println(Thread.currentThread().getName() + " done.");// 打印结束标记
                 long duratingMainTime = System.currentTimeMillis() - startMainTime;

                 System.out.println("All total time is: " + duratingMainTime + "ms");
                 // System.out.println("Start Thread numbers: " + THREAD_NUMBER);
                 // System.out.println("number is increased to: " + number);
         } catch (Exception e) {
                 e.printStackTrace();
         }
	}*/

}
